home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / ead / ead23.dms / ead23.adf / Listati / Calc.c < prev    next >
C/C++ Source or Header  |  1990-05-29  |  7KB  |  217 lines

  1. /* **************************************************************
  2.  
  3. Programma ...... Calc.c
  4.  
  5. Versione ....... 2.01, 1 Maggio 1990
  6.  
  7. Scopo .......... Calcolo di espressioni ASCII con numeri f.p.
  8.  
  9. Autore ......... Luigi Callegari. Fidonet: 2:331/101.0 (AmnesiA)
  10.  
  11. Hardware ....... Amiga standard 500/2500, Kickstart V1.2/1.3/1.4
  12.  
  13. Software ....... Lattice C V5.04, Aztec C V5.0a
  14.  
  15. Make Lattice ... LC -vbr -Lntvm -O -fi -ms Calc
  16.  
  17. Make Aztec ..... CC -fa -sb -so Calc, LN calc -lma -lc
  18.  
  19. ************************************************************** */
  20.  
  21. #define MAXOPL 5  /* Massimo numero di livelli */
  22. #define MAXELE 50 /* Massimo numero di operandi aritmetici */
  23. #define NOP 0     /* Token di "nessuna operazione" */
  24. #define ADD 1     /* Token di somma aritmetica */
  25. #define SUB 2     /* Token di sottrazione aritmetica */
  26. #define MUL 3     /* Token di moltiplicazione aritmetica */
  27. #define DIV 4     /* Token di divisione aritmetica */
  28. #define POW 5     /* Token di elevazione a potenza */
  29. #define PRIOR POW /* Operazione prioritaria per importanza */
  30.  
  31. #define isoper(c) (c=='+'||c=='-'||c=='/'||c=='*'||c=='^')
  32.  
  33. #include <string.h>        /* Funzioni di gestione stringa */
  34. #include <stdlib.h>        /* Funzioni di libreria standard */
  35. #include <ctype.h>         /* Funzioni isxxxx() */
  36. #include <stdio.h>         /* I/O Standard */
  37. #include <math.h>          /* Matematica */
  38. #include <libraries/dos.h> /* Gestione AmigaDOS */
  39.  
  40. #ifdef LATTICE
  41. #  include <proto/all.h>
  42. #else
  43. #  include <functions.h>
  44. #endif
  45.  
  46. double num[ MAXELE ];          /* Matrice Operandi */
  47. int op[ MAXELE ][ MAXOPL ];    /* Matrice Operatori aritmetici */
  48. int lev;                       /* Livello operatori */
  49. int nop;                       /* Numero effettivo operatori */
  50. int nel;                       /* Numero effettivo operandi */
  51. char *buf;                     /* Buffer per elaborazione batch */
  52. BPTR lucc;                     /* Lock di file */
  53.  
  54. /* ******** Uscita da errore con messaggio di postmortem ****** */
  55.  
  56. void die( char *s )  /* Puntatore a messaggio di errore */
  57. {
  58.    if ( lucc ) UnLock( lucc );
  59.    fprintf( stderr, "\n%s\n", s );
  60.    exit( 10L );
  61. }
  62.  
  63. /* Ritorna lunghezza in caratteri di una stringa ASCII rappresentante
  64. un numero in virgola mobile, con eventuale notazione esponenziale */
  65.  
  66. int luncifra( char *s )
  67. {
  68.    int j = 0;
  69.    
  70.    while ( isdigit( s[ j ] ) ) ++j;    /* Salta parte intera */
  71.    if ( s[ j ] == '.' )
  72.       {
  73.       ++j;
  74.       while ( isdigit( s[ j ] ) ) ++j; /* Salta eventuali decimali */
  75.       }
  76.    
  77.    if ( s[ j ] == 'e' || s[ j ] == 'E' )
  78.       {
  79.       ++j;                             /* Salta parte esponenziale */
  80.       if ( s[ j ] == '+' || s[ j ] == '-' )
  81.          ++j;
  82.       while( isdigit( s[ j ] ) ) ++j;
  83.       }
  84.  
  85.    return( j );
  86. }
  87.  
  88. /* ************ Corregge matrici dopo una operazione ********** */
  89.  
  90. void compr( int *k ) /* Puntatore a posizione di operando usato */
  91. {
  92.    unsigned short int j, i; /* Variabili di lavoro */
  93.   
  94.    --nop;  --nel;    /* Aggiusta contatori di operatori e operandi */
  95.   
  96.    for ( j=*k ; j<nel ; j++ ) /* Elimina operando usato */
  97.      num[ j+1 ] = num[ j+2 ];
  98.  
  99.    for ( i=0 ; i<MAXOPL ; i++ ) /* Elimina operatore usato */
  100.       for ( j=*k ; j<nop ; j++ )
  101.          op[ j ][ i ] = op[ j+1 ][ i ];
  102.      
  103.    *k -= 1; /* Riporta puntatore scansione a posizione corretta */
  104.    return;
  105. }
  106.  
  107. /*************** Memorizza operandi ed operatori ***************/
  108.  
  109. void parse( char *s ) /* Stringa ASCII dell'espressione */
  110. {
  111.    int c;                  /* Carattere da esaminare */
  112.    int j;                  /* Variabili di lavoro */
  113.    short operation;        /* Operazione da eseguire */
  114.   
  115.    for ( j=0 ; j<strlen(s) ; j++ ) {
  116.       c = s[ j ];
  117.      
  118.       if ( c == ')' && --lev < 0 )
  119.          die( "Troppe parentesi chiuse!" );
  120.     
  121.       else if ( c == '(' && ++lev == MAXOPL )
  122.          die( "Troppe parentesi aperte!" );
  123.     
  124.       else if ( isoper( c ) ) {       /* Memorizza operatore */
  125.          switch( c ) {
  126.             case '^' : operation = POW; break;
  127.             case '+' : operation = ADD; break;
  128.             case '-' : operation = SUB; break;
  129.             case '*' : operation = MUL; break;
  130.             case '/' : operation = DIV; break;
  131.             default  : operation = NOP; break;
  132.             }                          /* end switch(c) */
  133.          op[ nop++ ][ lev ] = operation;
  134.          }                             /* end else if() */
  135.      
  136.       else if ( isdigit( c ) ) {       /* Memorizza operando */
  137.          num[ nel++ ] = (double) atof( &s[ j ] ); 
  138.          if ( nel >= MAXELE )
  139.             die( "Troppi operandi!" );
  140.             
  141.          j += luncifra( &s[ j ] ) - 1; /* Salta numero inserito */
  142.          }                             /* end else if  */
  143.       }                                /* end for (j) */
  144.    return;
  145. }                                      /* end parse() */
  146.  
  147. /************ Esegue materialmente i calcoli ***************/
  148.  
  149. double calc( char *s ) /* Puntatore a stringa di espressione */
  150. {
  151.    int j, i;
  152.  
  153.    (void)parse( s ); /* Crea matrici operandi e operatori */
  154.  
  155.    for ( lev=MAXOPL-1 ; lev>=0 ; lev-- ) /* Da livello massimo */
  156.       {
  157.       for ( j=PRIOR ; j >= ADD ; j-- ) /* Da oper. prioritaria */
  158.          for ( i=0 ; i < nop; i++ )      /* Da primo operatore */
  159.             if ( op[ i ][ lev ] == j )
  160.                {
  161.                switch( op[ i ][ lev ] ) {
  162.                   case DIV: num[ i ] /= num[ i+1 ]; break;
  163.                   case MUL: num[ i ] *= num[ i+1 ]; break;
  164.                   case ADD: num[ i ] += num[ i+1 ]; break;
  165.                   case SUB: num[ i ] -= num[ i+1 ]; break;
  166.                   case POW: num[ i ] = pow(num[i],num[i+1]);break;
  167.                   default :                         break;
  168.                   } /* end switch */
  169.  
  170.                   compr( &i );      /* Aggiorna matrici */
  171.             }                       /* end if */
  172.       }                             /* end for (lev) */
  173.    return( num[ 0 ] );
  174. }
  175.  
  176. /* ********** Funzione trasferimento file in buffer ************ */
  177. char *makebuf( char *s )
  178. {
  179.    struct FileInfoBlock *fib;
  180.    char *ptr;
  181.    LONG lunfile;
  182.    BPTR fileh;
  183.    
  184.    if (!(lucc=Lock(s, ACCESS_READ) ) ) die("Locking impossibile!");
  185.  
  186.    if (!(fib=(struct FileInfoBlock*)malloc(sizeof(struct FileInfoBlock))))
  187.       die( "Manca memoria per FIB" );
  188.  
  189.    if ( ! Examine( lucc, (BPTR) fib ) ) die( "Non esamino file!" );
  190.    
  191.    lunfile = fib -> fib_Size; UnLock( lucc ); lucc = (BPTR) NULL;
  192.    
  193.    if ( ! (ptr = (char *) malloc( lunfile ) ) ) die("Manca memoria");
  194.    
  195.    if ( ! (fileh=Open( s, MODE_OLDFILE ))) die("Non si apre il file");
  196.    if ( Read( fileh, ptr, lunfile ) != lunfile) die("Errore di I/O");
  197.    Close( fileh );
  198.    
  199.    return( ptr );
  200. }
  201.  
  202. /************ Funzione principale *****************/
  203.  
  204. void main( int argc, char *argv[] )
  205. {  
  206.    if ( argc != 2 ) {            /* Sintassi errata */
  207.       printf( "\nSintassi: %s [expr]\n", argv[ 0 ] );
  208.       exit( 10L );
  209.       }
  210.  
  211.    if ( isalpha( argv[1][0] ))   /* Dato un nome di file */  
  212.       printf("File %s = %.8g\n", argv[1], calc(makebuf(argv[1])));
  213.    else                          /* Data un'espressione */
  214.       printf( "%s = %.8g\n", argv[ 1 ], calc( argv[ 1 ] ) );
  215.    exit( 0L );
  216. }
  217.